#include "tpch_kv.h"
#include <iostream>
#include <time.h>
#define MAX_ITEM_NUM 1000000
using namespace std;

static __inline__ unsigned long long rdtsc(void)	 
{	 
	unsigned hi, lo; 	
	__asm__ __volatile__ ("rdtsc" : "=a"(lo),"=d"(hi));	 
	return ( (unsigned long long)lo)|( ((unsigned long long)hi)<<32 );	 
} 

int main()
{
    unsigned long long int begin, stop,total=0;	
    CustomerItem *items = new CustomerItem[MAX_ITEM_NUM + 1];   // �ǰ�ȫ�������ܣ����׵�ַ����TEE�У���TEE����ocallֱ�ӷ���
    CustomerBucket cust_bucket;                                 // ����Ͱ
    clock_t start, end;
    double during = 0;
    Variant var;
    for (int i = 1;i <= MAX_ITEM_NUM;i++) {
        items[i].CustomerKey = i;
        items[i].Comment = "hello" + to_string(i);
        items[i].Name = "hello" + to_string(i);
        items[i].Address = "hello" + to_string(i);
        items[i].Phone = "hello" + to_string(i);
        items[i].Acctbal = "hello" + to_string(i);
        items[i].Mktsegment = "hello" + to_string(i);
        
    }
    // ���ò���Ŀ��
    items[1].Comment = "hello";
    items[10].Comment = "hello";
    for (int i = 500000;i <= 600000;i++) {
        items[i].Comment == "hello";
    }

    Variant var1 = "hello";
    CustomerItem item = items[10];

    // �������Ƶ�μ������� ��һ��ά��Ϊ�ֶ��±�����
    AccessCounter ac_counter;       
    // �Զ�����ʰ���
    ac_counter[C_COMMENT_COUNTER][item.CustomerKey]++;     // ����������
    ac_counter[C_CUSTKEY_COUNTER][item.CustomerKey]++;
    ac_counter[C_COMMENT_COUNTER][1] = 10;
    // �����ֶ����Ʋ鿴�������鿴���
    
    for (size_t i = 0;i < ac_counter.size(); i++) {
        cout << "Field: " << FieldNameList[i] << endl;
        if (ac_counter.size() != 0) {
            for (Counter::iterator it = ac_counter[i].begin(); it != ac_counter[i].end(); it++) {
                cout << "primary key = " << it->first << " " << "counter = " << it->second << "; "; 
            }
            cout << "\n==============\n";
        }
    }
    
    // ��ʼ��Ͱ���涪��Ͱ�ĸ���Ӧ�����ֶθ�����ͬ��Ͱ����Ӧ�ü�¼<�ֶ�ֵ��{��������}>
    for (size_t i = 0; i <= C_COMMENT_COUNTER; i++) {
        if (ac_counter[i].size()) { // ������ֶμ�������������
            for (Counter::iterator it = ac_counter[i].begin(); it != ac_counter[i].end(); it++) {
                if (it->second != 0) {  // ������ʴ�������1
                    int index = it->first;
                    switch (i)
                    {
                        case C_CUSTKEY_COUNTER: cust_bucket[i][items[index].CustomerKey].push_back(it->first); break;  // bucketitem
                        case C_NAME_COUNTER: cust_bucket[i][items[index].Name].push_back(it->first); break;  // bucketitem
                        case C_ADDRESS_COUNTER: cust_bucket[i][items[index].Address].push_back(it->first); break;  // bucketitem
                        case C_NATION_COUNTER: cust_bucket[i][items[index].Nation].push_back(it->first); break;  // bucketitem
                        case C_PHONE_COUNTER: cust_bucket[i][items[index].Phone].push_back(it->first); break;  // bucketitem
                        case C_ACCTBAL_COUNTER: cust_bucket[i][items[index].Acctbal].push_back(it->first); break;  // bucketitem
                        case C_MKTSEGMENT_COUNTER: cust_bucket[i][items[index].Mktsegment].push_back(it->first); break;  // bucketitem
                        case C_COMMENT_COUNTER: cust_bucket[i][items[index].Comment].push_back(it->first); break;  // bucketitem
                        default: break;
                    }
                    
                }
            }
        }
    }
    start = clock();
    // ��bucket�в���
    begin = rdtsc();
    for (BucketItem::iterator it = cust_bucket[C_COMMENT_COUNTER].begin();it != cust_bucket[C_COMMENT_COUNTER].end(); it++) {
        var = it->first;
        int type_id = var.index();
        /*
        switch (type_id)
        {
            case 0: int32_t va = std::get<0>(var);
            case 1: string va = std::get<1>(var);
            case 2: double va = std::get<2>(var)
            default: break;
        }
        */
        // string str = std::get<1>(var);
        if (var == var1) {
            // cout << it->second.size() << endl;
            cout << it->second.size() << " ";
            for (auto ii: it->second) {
                // cout << ii << " ";
            }
        }
    }
    stop = rdtsc();
    end = clock();
    during = (double)(end - start) / CLOCKS_PER_SEC;
    cout << "��ʱ: " << during << endl;
    cout << "CPUʱ��������: "<< stop - begin << endl;
    
    
    start = clock();
    begin = rdtsc();
    vector<int32_t> res;
    for (int i = 1;i <= MAX_ITEM_NUM;i++) {
        var = items[i].Comment;
        if (var == var1) {
            // cout << items[i].CustomerKey << " ";
            res.push_back(items[i].CustomerKey);
        }
        
    }
    cout << res.size() << " ";
    stop = rdtsc();
    end = clock();
    during = (double)(end - start) / CLOCKS_PER_SEC;
    cout << "��ʱ: " << during << endl;
    cout << "CPUʱ��������" << stop - begin << endl;

    return 0;
}